[BITS 16]
global _start

;%define _BOOT_DEBUG_     ; 做Boot Sector时把这行注释掉
						        ; 启用这行就用nasm Boot.asm -o Boot.com生成.com文件用于调试
						
%ifdef _BOOT_DEBUG_
   ORG  0100h
%else
   ORG 07c00h
%endif

CYLS EQU 10                ; 一共读取10个柱面, 共 10柱面*2面*18扇区*512字节 = 184320 byte = 180K
                           ; 加载到内存 0x8200 ~ 0x34fff

; 把软盘按Fat12格式填充
_start:
   JMP init                ; 跳转指令

   DB       0x90            ; 空 DB，DD用来写单字节
   DB       "NotOneOS"      ; 厂商名，8字节，DB用来写双字节
   DW       512             ; 每个扇区大小512字节，DW用来写4字节
   DB       1               ; 每个簇的扇区数
   DW       1               ; Boot占的扇区
   DB       2               ; 有2个FAT表
   DW       224             ; 根目录大小224
   DW       2880            ; 磁盘扇区总数 2880
   DB       0xf0            ; 介质描述符，磁盘种类必须为0xf0
   DW       9               ; 每个FAT扇区数
   DW       18              ; 每个磁道18个扇区
   DW       2               ; 2个磁头
   DD       0               ; 隐藏扇区数
   DD       2880            ; 同上，磁盘大小
   DB       0, 0, 0x29      ; 0x29 扩展引用标记
   DD       0xffffffff      ; 无意义，固定这么写
   DB       "NotOneOS   "   ; 磁盘名（卷标），11字节
   DB       "FAT12   "      ; 磁盘格式名，8字节
   RESB     18              ; 空18个字节，填充0x00

init:
   MOV      AX,0
   MOV      SS,AX
   MOV      SP,0x7c00      ; 堆栈空间，从0x7c00向前
   MOV      DS,AX

; 读取磁盘   
   MOV      AX,0x0820      ; 把磁盘数据加载到内存0x0820:0000处。 0x8000~0x81ff的512字节给BIOS加载引导区用的，所以这里从0x8200开始,
   MOV      ES,AX          ; 注意 ES:BX 是指向的地址，后面还需要对BX赋值0
; 初始化磁盘接口
   MOV      CH,0           ; 柱面 0
   MOV      DH,0           ; 磁头 0
   MOV      CL,2           ; 扇区 2

readloop:
   MOV      SI,0           ; 记录失败次数

retry:
   MOV      AH,0x02        ; 0x02 读磁盘
   MOV      AL,1           ; 读1个扇区
   MOV      BX,0
   MOV      DL,0x00        ; A驱动器

   INT      0x13           ; BIOS 读磁盘功能
   JNC      next           ; 成功跳转

   ADD      SI,1           ; 失败加一次
   CMP      SI,5           ; 到5次就跳到error
   JAE      error
   MOV      AH,0x00        ; 复位磁盘功能
   MOV      DL,0x00        ; A 驱动器
   INT      0x13           ; 重置磁盘驱动器
   JMP      retry          ; 重试
   
next:
   MOV      AX,ES          ; 内存地址向后移动0x0020
   ADD      AX,0x0020   
   MOV      ES,AX          ; 通过AX给ES加0x0020

   ADD      CL,1           ; 扇区+1
   CMP      CL,18          ; 有没有到18个扇区
   JBE      readloop       ; CL<=18,就跳到 readloop

   MOV      CL,1
   ADD      DH,1
   CMP      DH,2
   JB       readloop       ; 如果 DH < 2 ，则跳到readloop

   MOV      DH,0
   ADD      CH,1
   CMP      CH,CYLS
   JB       readloop       ; 如果CH<CYLS ， 则跳到readloop

; 读取磁盘后，跳转到系统文件NotOneOs.sys执行接下来的程序   
   MOV      [0x0ff0] , CH  ; 在0x0ff0处保存 CYLS的值，给后面的程序备用
   MOV      DH, 1          ; 加载磁盘成功置个标记
   MOV      SI , loading_msg  ; 显示正在加载
   JMP      print

; 打印错误信息
error:                  
   MOV      DH, 0          ; 加载失败置个标记
   MOV      SI , error_msg

; 使用前给SI赋值字符串地址
print:
   MOV      AL, [SI]
   ADD      SI, 1
   CMP      AL, 0          ; 字符串有没有读完，到0结束
   JE       end            ; 跳到结束程序
   MOV      AH, 0x0e       ; 显示一个字符
   MOV      BX, 15         ; 指定颜色
   INT      0x10           ; 调用BIOS功能显示字符
   JMP      print

end:
   CMP      DH, 1          ; 比较前面记录的加载成功标识
   JMP    0xc200           ; 跳转到磁盘上的系统程序,就是0x8000+0x4200=0xc200

loading_msg:
   DB "Loading NotOneOS..."; 想要开机后在屏幕上显示的字符串
   DB 0

error_msg:    
   DB "Error"              ; 失败
   DB 0

times  510-($-$$) db 0     ; 填充剩下的空间，使生成的二进制代码恰好为512字节 $$表示一个section的开始处汇编后地址
DW  0xaa55                 ; 结束标志

; 启动扇区以外部分输出

		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	4600
		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	1469432